#include "hw/misc/utils.h"

// 读取JSON文件并解析为cJSON对象
cJSON *read_json(const char *filename) {
    FILE *fp = NULL;
    long file_size;
    char *buffer = NULL;
    size_t read_size;
    cJSON *json = NULL;

    // 打开文件（二进制模式避免换行符问题）
    fp = fopen(filename, "rb");
    if (!fp) {
        perror("Error opening file for reading");
        return NULL;
    }

    // 获取文件大小
    if (fseek(fp, 0, SEEK_END) || (file_size = ftell(fp)) < 0 || fseek(fp, 0, SEEK_SET)) {
        perror("Error determining file size");
        fclose(fp);
        return NULL;
    }

    // 分配内存并读取内容
    buffer = (char*)malloc(file_size + 1);
    if (!buffer) {
        fprintf(stderr, "Memory allocation failed\n");
        fclose(fp);
        return NULL;
    }
    read_size = fread(buffer, 1, file_size, fp);
    fclose(fp); // 立即关闭文件

    if (read_size != (size_t)file_size) {
        fprintf(stderr, "File read error\n");
        free(buffer);
        return NULL;
    }
    buffer[file_size] = '\0'; // 添加字符串终止符

    // 解析JSON
    json = cJSON_Parse(buffer);
    free(buffer); // 释放原始数据

    if (!json) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr) {
            fprintf(stderr, "JSON parse error before: %s\n", error_ptr);
        }
    }

    return json;
}

// 将cJSON对象写入JSON文件
int write_json(const char *filename, const cJSON *root) {
    FILE *fp = NULL;
    char *json_str = NULL;
    size_t write_size;

    if (!root) {
        fprintf(stderr, "Invalid JSON object\n");
        return -1;
    }

    // 生成格式化JSON字符串
    json_str = cJSON_Print(root);
    if (!json_str) {
        fprintf(stderr, "Failed to generate JSON string\n");
        return -1;
    }

    // 打开文件写入（二进制模式）
    fp = fopen(filename, "wb");
    if (!fp) {
        perror("Error opening file for writing");
        free(json_str);
        return -1;
    }

    // 写入文件并检查完整性
    write_size = fwrite(json_str, 1, strlen(json_str), fp);
    free(json_str); // 立即释放JSON字符串

    if (fclose(fp) != 0) {
        perror("Error closing file");
        return -1;
    }

    return 0;
}

uint8_t hex_string_to_uint8(const char *hex_str){
	unsigned long value = strtoul(hex_str, NULL, 16);
	return (uint8_t)value;
}